package com.zyk.attach;

import com.zyk.utils.ProcessUtils;
import com.zyk.utils.WhereIsUtils;
import net.bytebuddy.agent.ByteBuddyAgent;

import java.io.*;
import java.util.ArrayList;
import java.util.List;

public class VM {

    public static String currentPid() {
        return ByteBuddyAgent.ProcessProvider.ForCurrentVm.INSTANCE.resolve();
    }

    public static List<VMDescriptor> getExternalVMList() throws Exception {
        File jpsCommand = WhereIsUtils.findJPS();
        if (null == jpsCommand) {
            throw new Exception("jps command not found");
        }

        List<String> list = new ArrayList<>();
        ByteArrayOutputStream bos = new ByteArrayOutputStream();
        ProcessUtils.start(new ProcessBuilder(jpsCommand.getAbsolutePath(), "-lv"), bos);
        String line;
        BufferedReader reader = new BufferedReader(new InputStreamReader(new ByteArrayInputStream(bos.toByteArray())));
        while ((line = reader.readLine()) != null) {
            list.add(line);
        }
        bos.close();
        reader.close();

        List<VMDescriptor> res = new ArrayList<>();
        String curPid = currentPid();
        for (String s : list) {
            String[] info = s.split(" ");
            if (curPid.equals(info[0])
                    || "sun.tools.jps.Jps".equals(info[1])
                    || "jdk.jcmd/sun.tools.jps.Jps".equals(info[1])) {
                continue;
            }
            res.add(new VMDescriptor(info[0], info[1]));
        }
        return res;
    }

    public static void attachVM(File agentFile, String pid, String args) {
        ByteBuddyAgent.attach(agentFile, pid, args);
    }



    public static class VMDescriptor {
        private final String pid;
        private final String name;

        public VMDescriptor(String pid, String name) {
            this.pid = pid;
            this.name = name;
        }

        public String getPid() {
            return pid;
        }

        public String getName() {
            return name;
        }

        @Override
        public String toString() {
            return "VMDescriptor{" +
                    "pid=" + pid +
                    ", name='" + name + '\'' +
                    '}';
        }
    }

}
